/*
    RExLib project, file dbconnector.cpp
    Copyright (C) 2012  Sarvaritdinov Ravil ra9oaj@gmail.com

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/


#include "dbconnector.h"

namespace rex {

DBconnector::DBconnector()
{
  _driver = 0;
  _driver = 0;
  _gstate = DB_UNCONNECTED;
  _dbname = 0;
  _dbuser = 0;
  _dbpasswd = 0;
}

DBconnector::DBconnector ( const DBconnector& other )
{

}

DBconnector::~DBconnector()
{
  closeDB();

  delete[] _drname;
  delete[] _dbname;
  delete[] _dbpasswd;
  delete[] _dbuser;
}

DBconnector& DBconnector::operator= ( const DBconnector& other )
{
  return *this;
}

bool DBconnector::operator== ( const DBconnector& other ) const
{
///TODO: return ...;
}

void DBconnector::setDBdriver ( const char* driver )
{
  if ( !strlen ( driver ) )
    return;

  _drname = ( char* ) malloc ( strlen ( driver ) +1 );
  _drname = strcat ( _drname,driver );
}

void DBconnector::setDBName ( const char* name )
{
  if ( _driver )
    _driver->setDBName ( name );
  else
    {
      if ( _dbname )
        delete[] _dbname;

      if ( !name )
        return;

      _dbname = new char[strlen ( name )];
      strcpy ( _dbname,name );
    }
}

void DBconnector::setDBUser ( const char* username, const char* passw )
{
  if ( _driver )
    _driver->setDBUser ( username,passw );
  else
    {
      if ( _dbuser )
        {
          delete[] _dbuser;
          _dbuser = 0;
        }

      if ( _dbpasswd )
        {
          delete[] _dbpasswd;
          _dbpasswd = 0;
        }

      if ( username )
        {
          _dbuser = new char[strlen ( username )];
          strcpy ( _dbuser,username );
        }

      if ( passw )
        {
          _dbpasswd = new char[strlen ( passw )];
          strcpy ( _dbpasswd,passw );
        }
    }
}

void DBconnector::setSSLConnection ( bool sslf )
{
  if ( _driver )
    _driver->setSSLConnection ( sslf );
}

void DBconnector::setUnixConnection ( bool unixf )
{
  if ( _driver )
    _driver->setUnixConnection ( unixf );
}

bool DBconnector::openDB ( const char* host, uint port )
{
  if ( !_drname )
    {
      _gstate = DB_ERROR;
      _gerror = DBE_DRIVER;

      return false;
    }

  char *drfile = 0;
  drfile = ( char * ) malloc ( strlen ( "dbdrivers/libdri.so" ) + strlen ( _drname ) + 1 );
  drfile = strcat ( drfile,"dbdrivers/libdri" );
  drfile = strcat ( drfile,_drname );
  drfile = strcat ( drfile,".so" );

  _dldriver = dlopen ( drfile,RTLD_LAZY );
  if ( !_dldriver )
    {
      fprintf ( stderr,"DBconnector: error  load driver file.\r\n" );
      return false;
    }

  DBconnectorPrivate* ( *newfunc ) ();
  newfunc = ( DBconnectorPrivate* ( * ) () ) dlsym ( _dldriver,"getDriver" );
  if ( !newfunc )
    return false;

  _driver = ( DBconnectorPrivate* ) ( ( *newfunc ) () );
  if ( !_driver )
    return false;
  _driver->setDBName ( _dbname );
  _driver->setDBUser ( _dbuser,_dbpasswd );
  return _driver->openDB ( host,port );
}

bool DBconnector::closeDB()
{
  if ( _driver && _dldriver )
    {
      bool res = _driver->closeDB();
      _gstate = _driver->dbState();
      _gerror;
      void ( *func ) ( DBconnectorPrivate* ) = ( void ( * ) ( DBconnectorPrivate* ) ) dlsym ( _dldriver,"removeDriver" );
      if ( func )
        ( *func ) ( _driver );

      dlclose ( _dldriver );
      _driver = 0;
      return res;
    }

  return false;
}

int DBconnector::query ( const char* qry )
{
  if ( _driver )
    return _driver->query ( qry );
  return -1;
}

long long unsigned int DBconnector::rowCount() const
{
  if ( _driver )
    return _driver->rowCount();
  return 0;
}

unsigned int DBconnector::fieldCount() const
{
  if ( _driver )
    return _driver->fieldCount();
  return 0;
}

long long unsigned int DBconnector::affectedRows() const
{
  if ( _driver )
    return _driver->affectedRows();
  return 0;
}

bool DBconnector::seek ( long long unsigned int pos )
{
  if ( _driver )
    return _driver->seek ( pos );
  return false;
}

bool DBconnector::next()
{
  if ( _driver )
    return _driver->next();
  return false;
}

bool DBconnector::first()
{
  if ( _driver )
    return _driver->first();
  return false;
}

char* DBconnector::value ( int val )
{
  if ( _driver )
    return _driver->value ( val );
  return 0;
}

int DBconnector::nativeErrorNo() const
{
  if ( _driver )
    return _driver->nativeErrorNo();
  return 0;
}

const char* DBconnector::nativeErrorString() const
{
  if ( _driver )
    return _driver->nativeErrorString();

  return 0;
}

int DBconnector::dbState() const
{
  if ( _driver )
    return _driver->dbState();

  return _gstate;
}

const char* DBconnector::errorString() const
{
  if ( _driver )
    return _driver->errorString();

  return 0;
}

int DBconnector::errorCode() const
{
  if ( _driver )
    return _driver->errorCode();

  return _gerror;
}

}